package com.example.casdemo;

import cn.hutool.core.util.IdcardUtil;
import cn.hutool.http.HttpUtil;
import com.sun.deploy.net.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description:
 * @Author: yangWei
 * @Version: 1.0
 */
@Slf4j
@Controller
public class CASController {

    String casHome = "http://cas.server.com:8443/cas";


    String callbackUrl = "http://cas.client1.com:9999/auth/authUser";


    String LOGIN = "login";

    private static ConcurrentHashMap<String, String> session = new ConcurrentHashMap<>();

    @RequestMapping("index")
    public String index(ModelMap map) {
        map.addAttribute("name", "clien B");
        return "index";
    }

    @RequestMapping("auth/authUser" )
    public void hello(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 如果客户端没有携带 ticket 那么返回cas服务器 他会指导客户登录 并携带 ticket
            String ticket = request.getParameter("ticket");
            if (StringUtils.isEmpty(ticket)) {
                String loginUrl = getLoginUrl(casHome, callbackUrl);
                response.sendRedirect(loginUrl);
                return;
            }
            // 客户端携带了ticket 校验
            String url = constructValidationUrl(ticket, callbackUrl, casHome);
            String res = HttpUtil.get(url);
            log.info(res);

            if(res.startsWith("yes")){
                String sessionId = UUID.randomUUID().toString();
                session.put(sessionId,res);
                response.addCookie(getCookie("JSESSIONID",sessionId,"/",Integer.MAX_VALUE));
                response.sendRedirect("http://cas.client1.com:9999/hello");
            }


        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @RequestMapping("hello")
    public String hello(ModelMap map,HttpServletRequest request) {

        Cookie[] cookies = request.getCookies();
        for (int i = 0; i < cookies.length; i++) {
            Cookie cookie = cookies[i];
            log.info("cookiename="+cookie.getName()+",cookieVal="+cookie.getValue());
            if(cookie.getName().equals("JSESSIONID")){
                String attribute = session.get(cookie.getValue());
                map.addAttribute("nickname", attribute);
                break;
            }
        }
        return "hello";
    }


    public Cookie getCookie(String name,String value,String path,int maxAge){
        Cookie cName = new Cookie(name, value);
        cName.setPath("/");
        cName.setMaxAge(maxAge);
        return cName;
    }

    public String getLoginUrl(String casHome, String callbackUrl) {
        StringBuilder sb = new StringBuilder();
        sb.append(casHome);
        if (!casHome.endsWith("/")) {
            sb.append("/");
        }
        sb.append(LOGIN).append("?");
        sb.append("service").append("=").append(encodeUrl(callbackUrl));
        return sb.toString();
    }

    /**
     * <h1>得到 ticket 验证ticket 封装的url路径</>
     * Cas20ProxyTicketValidator 前缀=proxyValidate
     * Cas10TicketValidator = validate          该接口是1.0时候的接口 返回的是一个用户字符串
     * Cas20ServiceTicketValidator = serviceValidate        该接口为2.0接口返回的是xml文件
     * Cas30ProxyTicketValidator = p3/proxyValidate         和下面一样
     * Cas30ServiceTicketValidator =p3/serviceValidate       返回了更多关于服务器的信息
     * 根据深圳大学xml文档参考他们使用的是 org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter 过滤器工作的 每个过滤器 前缀都不一样
     * <li> 例子url http://cas.server.com:8443/cas/serviceValidate?ticket=ST-6-hCu5J9Ufl1juUhkjQ-YqT4fNbdA-DESKTOP-OO0AUN0&service=http%3A%2F%2Fcas.client1.com%3A9002%2Fhello<li/>
     *
     * @param ticket
     * @param serviceUrl
     * @param casServerUrlPrefix
     * @return
     */
    protected final String constructValidationUrl(final String ticket, final String serviceUrl, String casServerUrlPrefix) {
        final StringBuilder buffer = new StringBuilder();
        buffer.append(casServerUrlPrefix);
        if (!casServerUrlPrefix.endsWith("/")) {
            buffer.append("/");
        }
        buffer.append("validate");
        buffer.append("?")
                .append("ticket").append("=").append(encodeUrl(ticket)).append("&")
                .append("service").append("=").append(encodeUrl(serviceUrl));

        return buffer.toString();
    }

    protected final String encodeUrl(final String url) {
        if (url == null) {
            return null;
        }
        try {
            return URLEncoder.encode(url, "UTF-8");
        } catch (final UnsupportedEncodingException e) {
            return url;
        }
    }
}
